import type { target } from "./index.d"
import { mutableHandlers, readonlyHandlers, baseHandlers, shallowReadonlyHandlers } from "./baseHandlers";
import { isObject } from "../shared/index";

/**reactive的一些特殊属性的枚举 */
export const enum ReactiveFlags {
    /**是否是reactive响应式对象 */
    IS_REACTIVE = "__v_isReactive",
    /**是否是只读的reactive响应式对象 */
    IS_READONLY = "__v_isReadonly",
}

/** reactive函数。可修改、会递归子属性为Proxy
 * @param raw 接收一个初始化对象
 */
export function reactive<T extends target>(raw: T): T {
    return createActiveObject<T>(raw, mutableHandlers)
}
/** reactive函数的 readonly 版本，只可读，不可修改，会递归子属性为Proxy
 * @param raw 接收一个初始化对象
 */
export function readonly<T extends target>(raw: T): T {
    return createActiveObject<T>(raw, readonlyHandlers)
}
/** reactive函数的 的 readonly版本 的 非递归版本，表层是readonly，内部属性都是普通的对象
 * @param raw 接收一个初始化对象
 */
export function shallowReadonly<T extends target>(raw: T): T {
    return createActiveObject<T>(raw, shallowReadonlyHandlers)
}


/**判断是否是reactive对象 */
export function isReactive(raw: target) {
    return !!raw[ReactiveFlags.IS_REACTIVE] //调用这个，会触发Proxy的get，在里面我们进行判断，如果读取的key叫“is_reacrive”，那就返回结果
    //如果不是reactive数据，因为没有这个属性，所以会得到undefined，我们通过!!来把undefined转为布尔值即可
}
/**判断是否是readonly的reactive */
export function isReadonly(raw: target) {
    return !!raw[ReactiveFlags.IS_READONLY] //调用这个，会触发Proxy的get，在里面我们进行判断，如果读取的key叫“is_reacrive”，那就返回结果
    //如果不是reactive数据，因为没有这个属性，所以会得到undefined，我们通过!!来把undefined转为布尔值即可
}
/**判断这个数据，是否是由 reactive 或 readonly 生成的Proxy数据 */
export function isProxy(raw: target) {
    return isReactive(raw) || isReadonly(raw)
}

/** 创建响应式对象
 * @param raw 接收一个初始化对象
 * @param baseHandlers Proxy的处理器
 */
function createActiveObject<T extends target>(raw: T, baseHandlers: baseHandlers): T {
    if (!isObject(raw)) {
        console.warn(`target [${raw}] 必须是一个对象`);
        return raw
    }
    return new Proxy<T>(raw, baseHandlers)
}

